package com.example.hetong_system.controller;

import com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.payment.page.models.AlipayTradePagePayResponse;
import com.example.hetong_system.model.PaymentPlan;
import com.example.hetong_system.repository.PaymentPlanRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.net.URLDecoder;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@RestController
public class AlipayController {

    @Autowired
    private PaymentPlanRepository paymentPlanRepository;

    @PostMapping("/alipay/pay")
    public Map<String, Object> pay(@RequestBody Map<String, String> params) {
        Map<String, Object> result = new HashMap<>();
        try {
            // 1. 参数校验与付款计划查询
            String paymentPlanId = params.get("paymentPlanId");
            if (paymentPlanId == null || paymentPlanId.isEmpty()) {
                result.put("success", false);
                result.put("message", "缺少付款计划ID");
                return result;
            }

            PaymentPlan plan = paymentPlanRepository.findById(Long.valueOf(paymentPlanId))
                    .orElseThrow(() -> new IllegalArgumentException("付款计划不存在"));

            if (plan.getIsExecuted()) {
                result.put("success", false);
                result.put("message", "该计划已支付，无需重复操作");
                return result;
            }

            // 2. 生成订单号并保存
            String outTradeNo = "PAY_" + plan.getId() + "_" + System.currentTimeMillis();
            plan.setOutTradeNo(outTradeNo);
            paymentPlanRepository.save(plan);

            // 3. 调用SDK生成支付表单
            AlipayTradePagePayResponse response = Factory.Payment.Page()
                    .pay(
                            "合同支付-" + plan.getContractId(),
                            outTradeNo,
                            plan.getAmount().toString(),
                            ""
                    );
            String payForm = response.getBody();

            // 4. 从action的URL中提取所有必要的公共参数
            Map<String, String> publicParams = extractPublicParamsFromAction(payForm);

            // 验证必要参数
            List<String> requiredParams = Arrays.asList("app_id", "method", "format", "charset", "sign_type", "timestamp", "version", "sign");
            for (String param : requiredParams) {
                if (!publicParams.containsKey(param) || publicParams.get(param).isEmpty()) {
                    System.out.println("❌ 缺少必要参数：" + param);
                    result.put("success", false);
                    result.put("message", "缺少必要参数：" + param);
                    return result;
                }
            }

            System.out.println("✅ 提取到所有公共参数：" + publicParams.keySet());

            // 5. 将所有公共参数添加为表单隐藏字段
            StringBuilder paramInputs = new StringBuilder();
            for (Map.Entry<String, String> entry : publicParams.entrySet()) {
                paramInputs.append("<input type=\"hidden\" name=\"")
                        .append(entry.getKey())
                        .append("\" value=\"")
                        .append(entry.getValue())
                        .append("\" />\n");
            }

            payForm = payForm.replace(
                    "<input type=\"hidden\" name=\"biz_content\"",
                    // 插入所有公共参数隐藏字段
                    paramInputs.toString() +
                            "<input type=\"hidden\" name=\"biz_content\""
            );

            // 6. 修正action URL，移除所有公共参数
            String cleanUrl = removeParamsFromUrl(getActionUrl(payForm), publicParams.keySet());
            payForm = payForm.replaceFirst("action=\"[^\"]+\"", "action=\"" + cleanUrl + "\"");

            // 7. 打印最终表单（调试用）
            System.out.println("修正后的支付表单: " + payForm);

            // 8. 返回结果
            result.put("success", true);
            result.put("payForm", payForm);
            result.put("outTradeNo", outTradeNo);
            return result;

        } catch (Exception e) {
            e.printStackTrace();
            result.put("success", false);
            result.put("message", "支付请求失败：" + e.getMessage());
            return result;
        }
    }

    // 从表单的action URL中提取所有公共参数
    private Map<String, String> extractPublicParamsFromAction(String form) throws Exception {
        Map<String, String> params = new HashMap<>();
        String actionUrl = getActionUrl(form);

        // 正则匹配URL中的所有参数
        Pattern pattern = Pattern.compile("([^?&]+)=([^&]+)");
        Matcher matcher = pattern.matcher(actionUrl);

        while (matcher.find()) {
            String key = URLDecoder.decode(matcher.group(1), "UTF-8");
            String value = URLDecoder.decode(matcher.group(2), "UTF-8");
            params.put(key, value);
        }

        return params;
    }

    // 获取表单的action URL
    private String getActionUrl(String form) {
        Pattern pattern = Pattern.compile("action=\"([^\"]+)\"");
        Matcher matcher = pattern.matcher(form);
        if (matcher.find()) {
            return matcher.group(1);
        }
        return "";
    }

    // 从URL中移除指定参数
    private String removeParamsFromUrl(String url, Set<String> paramNames) {
        String result = url;
        for (String param : paramNames) {
            // 移除 &param=value
            result = result.replaceAll("&" + param + "=[^&]*", "");
            // 移除 ?param=value&
            result = result.replaceAll("\\?" + param + "=[^&]*&", "?");
            // 移除 ?param=value (最后一个参数)
            result = result.replaceAll("\\?" + param + "=[^&]*$", "");
        }
        return result;
    }
}

//package com.example.hetong_system.controller;
//
//import com.alipay.easysdk.factory.Factory;
//import com.alipay.easysdk.payment.page.models.AlipayTradePagePayResponse;
//import com.example.hetong_system.model.PaymentPlan;
//import com.example.hetong_system.repository.PaymentPlanRepository;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.beans.factory.annotation.Value;
//import org.springframework.web.bind.annotation.*;
//
//import java.text.SimpleDateFormat;
//import java.util.*;
//import java.util.regex.Matcher;
//import java.util.regex.Pattern;
//
//@RestController
//public class AlipayController {
//
//    @Autowired
//    private PaymentPlanRepository paymentPlanRepository;
//
//    @Value("${alipay.appId}")
//    private String alipayAppId;
//
//    @PostMapping("/alipay/pay")
//    public Map<String, Object> pay(@RequestBody Map<String, String> params) {
//        Map<String, Object> result = new HashMap<>();
//        try {
//            // 1. 参数校验与付款计划查询
//            String paymentPlanId = params.get("paymentPlanId");
//            if (paymentPlanId == null || paymentPlanId.isEmpty()) {
//                result.put("success", false);
//                result.put("message", "缺少付款计划ID");
//                return result;
//            }
//
//            PaymentPlan plan = paymentPlanRepository.findById(Long.valueOf(paymentPlanId))
//                    .orElseThrow(() -> new IllegalArgumentException("付款计划不存在"));
//
//            if (plan.getIsExecuted()) {
//                result.put("success", false);
//                result.put("message", "该计划已支付，无需重复操作");
//                return result;
//            }
//
//            // 2. 生成订单号并保存
//            String outTradeNo = "PAY_" + plan.getId() + "_" + System.currentTimeMillis();
//            plan.setOutTradeNo(outTradeNo);
//            paymentPlanRepository.save(plan);
//
//            // 3. 调用SDK生成支付表单
//            AlipayTradePagePayResponse response = Factory.Payment.Page()
//                    .pay(
//                            "合同支付-" + plan.getContractId(),
//                            outTradeNo,
//                            plan.getAmount().toString(),
//                            ""
//                    );
//            String payForm = response.getBody();
//
//            // 4. 提取SDK生成的表单中的所有参数（包括签名）
//            Map<String, String> formParams = extractFormParams(payForm);
//
//            // 检查是否包含签名
//            if (!formParams.containsKey("signature")) {
//                System.out.println("❌ 警告：SDK生成的表单中不包含签名！");
//            } else {
//                System.out.println("✅ 已提取到SDK生成的签名");
//            }
//
//            // 5. 生成时间戳
//            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//            sdf.setTimeZone(TimeZone.getTimeZone("GMT+8"));
//            String timestamp = sdf.format(new Date());
//
//            // 6. 手动构建完整表单（包含所有必要参数和SDK生成的签名）
//            payForm = buildCompletePayForm(formParams, alipayAppId, timestamp);
//
//            // 7. 打印最终表单（调试用）
//            System.out.println("生成的支付表单: " + payForm);
//
//            // 8. 返回结果
//            result.put("success", true);
//            result.put("payForm", payForm);
//            result.put("outTradeNo", outTradeNo);
//            return result;
//
//        } catch (Exception e) {
//            e.printStackTrace();
//            result.put("success", false);
//            result.put("message", "支付请求失败：" + e.getMessage());
//            return result;
//        }
//    }
//
//    // 从表单中提取所有参数（包括签名）
//    private Map<String, String> extractFormParams(String form) {
//        Map<String, String> params = new HashMap<>();
//
//        // 正则表达式匹配所有隐藏输入字段
//        Pattern pattern = Pattern.compile("<input\\s+type=\"hidden\"\\s+name=\"([^\"]+)\"\\s+value=\"([^\"]*)\"\\s*/>");
//        Matcher matcher = pattern.matcher(form);
//
//        while (matcher.find()) {
//            String name = matcher.group(1);
//            String value = matcher.group(2);
//            params.put(name, value);
//        }
//
//        return params;
//    }
//
//    // 构建完整的支付表单，包含所有必要参数
//    private String buildCompletePayForm(Map<String, String> sdkParams, String appId, String timestamp) {
//        StringBuilder formBuilder = new StringBuilder();
//
//        // 构建表单开始部分
//        formBuilder.append("<form action=\"https://openapi-sandbox.dl.alipaydev.com/gateway.do\" method=\"POST\">\n");
//
//        // 添加SDK生成的所有参数（包括签名）
//        for (Map.Entry<String, String> entry : sdkParams.entrySet()) {
//            formBuilder.append("  <input type=\"hidden\" name=\"")
//                    .append(entry.getKey())
//                    .append("\" value=\"")
//                    .append(entry.getValue())
//                    .append("\" />\n");
//        }
//
//        // 添加额外需要的参数
//        formBuilder.append("  <input type=\"hidden\" name=\"method\" value=\"alipay.trade.page.pay\" />\n");
//        formBuilder.append("  <input type=\"hidden\" name=\"app_id\" value=\"")
//                .append(appId)
//                .append("\" />\n");
//        formBuilder.append("  <input type=\"hidden\" name=\"timestamp\" value=\"")
//                .append(timestamp)
//                .append("\" />\n");
//
//        // 表单结束
//        formBuilder.append("  <input type=\"submit\" value=\"立即支付\" style=\"display:none\" />\n");
//        formBuilder.append("</form>");
//
//        return formBuilder.toString();
//    }
//}